package com.vagavaga.bizworld.jpatx;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import javax.persistence.EntityManager;

class ChildEntityManager extends EntityManagerInterceptor {

    private final EntityManager original;
    @SuppressWarnings("unused")
    private final String persistenceUnitName;
    private boolean closed = false;

    private ChildEntityManager(EntityManager em, String persistenceUnitName) {
        original = em;
        this.persistenceUnitName = persistenceUnitName;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        chechIfClosed();
        if (CLOSE.equals(method)) {
            return null;
        }
        if (JOIN_TRANSACTION.equals(method)) {
            return null;
        }
        if (GET_TRANSACTION.equals(method)) {
            return getTransaction();
        }
        try {
            return method.invoke(original, args);
        } catch (InvocationTargetException ite) {
            throw ite.getTargetException();
        }
    }

    private Object getTransaction() {
        return ChildTransaction.wrap(original.getTransaction());
    }

    private void chechIfClosed() {
        if (closed) throw new IllegalStateException("EntityManager is already closed!");
    }

    public static EntityManager wrap(EntityManager em, String persistenceUnitName) {
        ChildEntityManager cem = new ChildEntityManager(em, persistenceUnitName);
        return (EntityManager) Proxy.newProxyInstance(
                em.getClass().getClassLoader(),
                new Class<?>[] { EntityManager.class },
                cem);
    }

}
